<script setup>
import CheckBoxOption from '@/views/components/CheckBoxOption.vue'
import SingleBlank from '@/views/components/SingleBlank.vue'
import RadioOption from '@/views/components/RadioOption.vue'
import FillBlank from '@/views/components/FillBlank.vue'
import { apiRecordInfo } from '@/api/exam.js'
import { computed, nextTick, onBeforeMount, reactive, ref } from 'vue'
import { useRoute } from 'vue-router'
import { setDocumentTitle } from '@/utils/util.js'
import { showImagePreview } from 'vant'
import MusicPlayer from './components/MusicPlayer.vue'
import { Throttle } from '@/utils/util'

const route = useRoute()

const state = reactive({
    info: {},
    groupList: [],
    articleTitle: '',
    currentTab: '答题记录',
    scrollYList: { tab1: 0, tab2: 0 }
})

const orgPassage = ref([]) // 原文 没有高亮样式带译文的原文

const highlightPassage = ref([]) // 有高亮样式的原文

const viewHighlight = ref(false) // 切换原文的时候是否是带高亮的

const showTranslate = ref(false) // 显示翻译

const partId = ref()

const listenAudio = ref('') // 音频地址

const musicComponent = ref(null)

const listenPassage = ref([]) // 听力原文

const currentHighlightIndex = ref(0) // 当前定位的文本位置

const lastHighlightedIndex = ref(null) // 当前定位的上一句文本位置

const lineRefs = ref([])

const tabList = computed(() => {
    if (topicType.value == 2) {
        return ['答题记录', '原文']
    }
    if (topicType.value == 1 && listenPassage.value.length) {
        return ['答题记录', '原文']
    } else {
        return []
    }
})

// 两种原文按需显示
const useOrgPassage = computed(() => {
    return viewHighlight.value ? highlightPassage.value : orgPassage.value
})

// 计算当前是否高亮某个索引的文本
const isHighlighted = computed(() => {
    // 如果当前索引是高亮索引，或者它是上一次高亮的索引（用于保持高亮连贯性）
    return currentHighlightIndex.value ?? lastHighlightedIndex.value
})

const topicType = computed(() => state.info.subjectType) // 听力还是阅读

onBeforeMount(() => {
    document.querySelector('body').setAttribute('style', 'background:#fff;')
    const query = route.query
    getDetail(query.id)
})

const getDetail = (id) => {
    apiRecordInfo(id).then((res) => {
        state.info = res
        setDocumentTitle(res.examExName)
        state.groupList = res.partList[0].groupList
        orgPassage.value = res.partList[0]?.translates
        state.articleTitle = res.partList[0].title
        partId.value = res.partList?.[0]?.partId
        listenPassage.value = res?.listenParagraphList || []
        listenAudio.value = res?.listenAudio || ''
    })
}

// 切换tab
const changeTab = (item) => {
    // 记录tab滚动的高度
    if (state.currentTab === '答题记录') {
        state.scrollYList.tab1 = window.scrollY
    } else if (state.currentTab === '原文') {
        state.scrollYList.tab2 = window.scrollY
    }

    state.currentTab = item
    setTimeout(() => {
        // 改变tab对应的高度
        if (state.currentTab === '答题记录') {
            window.scrollTo(0, state.scrollYList.tab1)
        } else if (state.currentTab === '原文') {
            window.scrollTo(0, state.scrollYList.tab2)
        }
    }, 0)
}

// 查看大图
const showBIgImage = (url) => {
    showImagePreview([url])
}

// 原文定位
async function handlePosition(val) {
    state.scrollYList.tab1 = window.scrollY
    if (state.info.subjectType == 2) {
        highlightPassage.value = val?.translates
        viewHighlight.value = true
        await nextTick()
        state.currentTab = '原文'
        pageScrollTOview('.high-light', 'center')
    } else {
        state.currentTab = '原文'
        musicComponent.value.setCurrentTime(val.beginTime / 1000)
        await nextTick()
        musicComponent.value.play()
    }
}

// 页面滚动到指定位置
async function pageScrollTOview(selector, position) {
    await nextTick()
    const targetElement = document.querySelector(selector)
    await nextTick()
    if (targetElement) {
        targetElement.scrollIntoView({ block: position, behavior: 'smooth' })
    }
}

// 监听播放器设置滚动高亮
function handlePlayerTimeUpdate(time = 0) {
    time = time * 1000
    let newIndex = currentHighlightIndex.value

    // 查找当前时间对应的文本索引
    for (let i = 0; i < listenPassage.value.length; i++) {
        const { beginTime: start, endTime: end } = listenPassage.value[i]
        if (start < time && end > time) {
            newIndex = i
            break
        }
    }

    // 如果找到了新的高亮文本，并且与上一次不同，则更新索引
    if (newIndex !== currentHighlightIndex.value) {
        // 如果上一次有高亮的文本，则保存其索引（用于保持高亮连贯性）
        currentHighlightIndex.value = newIndex
        lastHighlightedIndex.value = newIndex - 1 // 保存上一次高亮的索引（或null如果没有前一个）

        // 如果是最后一句文本并且播放时间已经超过其结束时间，则保持最后一句高亮
        if (newIndex === listenPassage.value.length - 1 && time >= listenPassage.value[newIndex].endTime) {
            currentHighlightIndex.value = listenPassage.value.length - 1
        }
        pageScrollTOview('.listen-highlight', 'center')
    }
}

const throttledHandlePlayerTimeUpdate = Throttle(handlePlayerTimeUpdate, 200) // 节流更新时间

// 切换翻译显示
function toggleTranslate() {
    showTranslate.value = !showTranslate.value
    if (state.info.subjectType == 1) {
        pageScrollTOview('.listen-highlight', 'center')
    }
}

// 听力原文点击文章某一段跳转到对应的音频位置播放
async function setPlay(i, item) {
    currentHighlightIndex.value = i
    musicComponent.value.setCurrentTime(item.beginTime / 1000)
    musicComponent.value.play()
    await nextTick()
    pageScrollTOview('.listen-highlight', 'center')
}

function whenPopShow() {
    musicComponent.value && musicComponent.value.pause()
}
</script>

<template>
    <div class="record-detail">
        <div class="class-list" v-if="tabList.length">
            <div
                class="class-item"
                :class="{ active: item === state.currentTab }"
                v-for="(item, index) in tabList"
                :key="index"
                @click="changeTab(item)">
                {{ item }}
            </div>
        </div>
        <div v-if="state.currentTab === '原文'" class="question-content">
            <!-- 阅读的原文 -->
            <template v-if="state.info['subjectType'] == 2">
                <div class="article-title" v-html="state.articleTitle"></div>
                <div class="html-content">
                    <template v-for="(item, index) in useOrgPassage" :key="index">
                        <div v-html="item.orgContent"></div>
                        <br>
                        <div v-show="showTranslate">
                            <div class="translate">{{item.content}}</div>
                            <br>
                        </div>
                    </template>
                </div>
            </template>
            <!-- 听力的原文 -->
            <template v-else-if="state.info['subjectType'] == 1">
                <div class="html-content">
                    <template v-for="(item, index) in listenPassage" :key="index">
                        <div
                            class="listen-passage-item"
                            ref="lineRefs"
                            :class="{'listen-highlight': index == isHighlighted}"
                            @click="setPlay(index, item)"
                        >
                            <div v-html="item.content"></div>
                            <div v-show="showTranslate">
                                <div class="translate">{{item.translate}}</div>
                            </div>
                        </div>
                    </template>
                </div>
            </template>
            <div class="end-flag">- End -</div>
            <div v-if="useOrgPassage?.length || listenPassage?.length" :class="['translate-btn', {'show-translate': showTranslate}]" @click="toggleTranslate">
                <img src="@/assets/ic_fanyi@2x.png" alt="">
            </div>
        </div>
        <template v-if="state.currentTab === '答题记录'">
            <div class="head-info" :class="{ 'margin-head': state.info.subjectType !== 2 }">
                <div class="flex-between">
                    <div class="bold-text">正确率</div>
                    <div class="bold-text">{{ state.info.accuracy }}</div>
                </div>
                <div class="flex-between">
                    <div>用时</div>
                    <div>{{ state.info.durationFormat }}</div>
                </div>
                <div class="flex-between">
                    <div>提交时间</div>
                    <div>{{ state.info.submitTime }}</div>
                </div>
            </div>
            <div class="content-blank">
                <div class="content" v-for="(item, index) in state.groupList" :key="index">
                    <div class="content-text" v-html="item.groupName" />
                    <div class="content-text" v-html="item.groupDesc" />
                    <div class="content-text" style="text-align: center;font-size: 17px;font-weight: bold;" v-html="item.title" />
                    <div class="imgUrl" v-if="item.imgUrl" @click="showBIgImage(item.imgUrl)">
                        <img :src="item.imgUrl" alt="" />
                    </div>
                    <template v-if="item.itemList">
                        <div
                            class="flex-item-start"
                            v-for="(sub, subIndex) in item.itemList"
                            :key="'sub' + subIndex">
                            <b class="num-text">{{ sub.optionCode }}</b>
                            <label>{{ sub.optionName }}</label>
                        </div>
                        <br />
                    </template>
                    <template v-if="item.itemTitle">
                        <div class="item-title" v-html="item.itemTitle" />
                    </template>
                    <FillBlank
                        v-if="item.type === 1 || item.type === 16"
                        :topicList="item.topicList"
                        :part-id="partId"
                        :topic-type="topicType"
                        :exam-id="state.info.examId"
                        @input-blue="saveTopic"
                        @to-position="handlePosition"
                        @popup-show="whenPopShow"
                        showAnswer="true"></FillBlank>
                    <SingleBlank
                        v-if="[7, 4, 3, 14, 12, 10, 11, 5, 9].includes(item.type)"
                        :topicList="item.topicList"
                        :part-id="partId"
                        :topic-type="topicType"
                        :exam-id="state.info.examId"
                        @input-blue="saveTopic"
                        @to-position="handlePosition"
                        @popup-show="whenPopShow"
                        showAnswer="true"></SingleBlank>
                    <radio-option
                        v-if="item.type === 2 || item.type === 15 || item.type === 8"
                        :topic-list="item.topicList"
                        :part-id="partId"
                        :topic-type="topicType"
                        :exam-id="state.info.examId"
                        @changeHandle="saveTopic"
                        @to-position="handlePosition"
                        @popup-show="whenPopShow"
                        showAnswer="true"></radio-option>
                    <check-box-option
                        v-if="item.type === 6"
                        :topic-list="item.topicList"
                        :part-id="partId"
                        :topic-type="topicType"
                        :exam-id="state.info.examId"
                        @changeHandle="saveTopic"
                        @to-position="handlePosition"
                        @popup-show="whenPopShow"
                        showAnswer="true"></check-box-option>
                    <div v-if="index + 1 < state.groupList.length" class="bottom-line"></div>
                </div>
            </div>
        </template>
        <div class="fixed-bottom" v-if="state.info.subjectType !== 2">
            <MusicPlayer
                v-if="listenAudio"
                ref="musicComponent"
                :url="listenAudio"
                :autoplay="false"
                @update-time="throttledHandlePlayerTimeUpdate"
            />
        </div>
    </div>
</template>

<style scoped lang="scss">
.num-text {
    font-weight: bold;
    font-size: 0.87rem;
    color: black;
    padding-right: 4px;
}
.record-detail {
    padding: 0 1rem 6rem 1rem;
}
.class-list {
    position: sticky;
    top: 0;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    background: #ffffff;
    width: 100%;
    z-index: 100;
    .class-item {
        padding: 0 15px;
        color: #999999;
        position: relative;
        text-align: center;
    }
    .active {
        color: #666666;
        font-weight: bold;
        font-size: 1rem;
    }
    .active::before {
        position: absolute;
        left: calc(50% - 9px);
        text-align: center;
        bottom: -4px;
        content: ' ';
        width: 18px;
        height: 3px;
        background: #fd453d;
        border-radius: 2px;
    }
}
.head-info {
    background: #f6f8fc;
    border-radius: 5px;
    padding: 10px;
    font-size: 0.867rem;
    color: #666666;
    .bold-text {
        font-weight: bold;
    }
}
.margin-head {
    margin-top: 1rem;
}
.flex-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.content {
    line-height: 30px;
    padding-top: 10px;
    .content-text {
        padding-bottom: 0;
    }
    .imgUrl {
        width: 100%;
        img {
            width: 100%;
            height: auto;
        }
    }
    .bottom-line {
        background-color: #f5f5f5;
        height: 5px;
    }
}
.question-content {
    line-height: 30px;
    word-break: break-word;
    .article-title {
        text-align: center;
    }
    :deep(.html-content) {
        ::v-deep img {
            width: 100% !important;
        }
        .translate{
            color: #999;
        }
        // 高亮的样式
        .wrap-highlight{
            background-color: rgba(68, 111, 236, .08);
            display: inline-block;
            padding: 0 .3rem;
            box-sizing: border-box;
            border-radius: .13rem;
        }
        .high-light{
            display: inline-block;
            padding: 0 .3rem;
            box-sizing: border-box;
            border-radius: .13rem;
        }
        .listen-passage-item{
            margin-bottom: 1rem;
        }
        .listen-highlight{
            background-color: rgba(68, 111, 236, .08);
            padding: 0 .3rem;
            box-sizing: border-box;
            border-radius: .13rem;
        }
    }
    .end-flag {
        font-size: 15px;
        color: #999999;
        text-align: center;
        line-height: 30px;
        height: 30px;
    }
    .translate-btn{
        width: 2.67rem;
        height: 2.67rem;
        border-radius: .67rem;
        background-color: rgba(102, 102, 102, .8);
        position: fixed;
        right: 1rem;
        bottom: 11.67rem;
        img{
            width: 1.13rem;
            height: 1.13rem;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
        }
    }
    .show-translate{
        background-color: rgba(117, 164, 255, .8);
    }
}
.fixed-bottom {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    padding-bottom: 1.333rem;
    background: hsla(0, 0%, 100%, 1);
}
.submit-btn {
    position: absolute;
    right: 30px;
    bottom: 2.2rem;
    font-size: 0.933rem;
    color: #fd453d;
    font-weight: bold;
}
.item-title{
    font-size: 17px;
    font-weight: bold;
    text-align: center;
}
</style>
